package com.xyzwps.collections.set

import com.xyzwps.collections.Range

import java.util.function.Supplier

import static org.junit.jupiter.api.Assertions.*

class TestSet {

    def static testAdd(Supplier<Set<Integer>> supplier) {
        def set = supplier.get()
        final int COUNT = 103
        for (int i : Range.create(COUNT)) {
            assertEquals set.size(), i
            set.add(i)
        }
        assertEquals set.size(), COUNT + 1

        for (int i : Range.create(COUNT)) {
            set.add(i)
            assertEquals set.size(), COUNT + 1
        }
    }

    def static testContains(Supplier<Set<Integer>> supplier) {
        def set = supplier.get()
        final int COUNT = 133
        for (int i : Range.create(COUNT)) set.add(i)


        for (int i : Range.create(-120, 232)) {
            if (i < 0) assertFalse set.has(i)
            else if (i <= COUNT) assertTrue set.has(i)
            else assertFalse set.has(i)
        }
    }

    def static testRemove(Supplier<Set<Integer>> supplier) {
        def set = supplier.get()
        final int COUNT = 133
        for (int i : Range.create(COUNT)) set.add(i)

        for (int i : Range.create(-212, 245)) {
            if (i < 0) {
                assertFalse set.has(i)
                assertFalse set.remove(i)
                assertEquals set.size(), COUNT + 1
            } else if (0 <= i && i <= COUNT) {
                assertTrue set.has(i)
                assertTrue set.remove(i)
                assertFalse set.has(i)
                assertEquals set.size(), COUNT - i
            } else {
                assertFalse set.has(i)
                assertFalse set.remove(i)
                assertEquals set.size(), 0
            }
        }
    }

    def static testClear(Supplier<Set<Integer>> supplier) {
        for (int size : Range.create(1, 20)) {
            def set = supplier.get()
            for (int i : Range.create(1, size)) set.add(i)
            assertEquals set.size(), size
            set.clear()
            assertEquals set.size(), 0
        }
    }

    def static testIterator(Supplier<Set<Integer>> supplier) {
        def set = supplier.get()
        final int COUNT = 133
        for (int i : Range.create(COUNT)) set.add(i)

        int times = 0
        for (int e : set) {
            assertTrue e in set
            times++
        }
        assertEquals times, COUNT + 1
    }

    def static testCommon(Supplier<Set<Integer>> supplier) {
        testAdd supplier
        testContains supplier
        testRemove supplier
        testClear supplier
        testIterator supplier
    }
}
